package aps.module_Machines;

//Java
import net.minecraft.src.Container;
import net.minecraft.src.ICrafting;
import net.minecraft.src.NBTTagCompound;
import net.minecraft.src.TileEntity;
import aps.module_Core.GuiIDs;
import aps.module_Core.InventoryAPS;
import aps.module_Core.TileEntityAPSPowered;
import aps.module_Core.module_Core.APSBlockTypes;
import buildcraft.api.core.Position;
import buildcraft.api.power.IPowerReceptor;
import buildcraft.core.network.PacketPayload;
import buildcraft.core.network.PacketUpdate;
import buildcraft.core.network.TileNetworkData;
import buildcraft.core.network.TilePacketWrapper;
//Vanilla Minecraft
//Buildcraft
//APS

public class TileEntityEnergyStore extends TileEntityAPSPowered implements IPowerReceptor
{
	static int MaxPowerStored = 1000000;
	static int MaxPowerIn = 500;
	static int MaxPowerOut = 500;
	
	int PowerLevel;
	float PowerIn;
	float PowerOut;
	int UserMaxPowerIn;
	int UserMaxPowerOut;
	
	
	int SideUpdateDelay = 0;
	boolean IsDraining;
	
	public static TilePacketWrapper updateMessageWrapper = new TilePacketWrapper(UpdateMessage.class);
	
	public TileEntityEnergyStore()
	{
		super( 0, 32, 1, 2, 0, 1, MaxPowerIn, 1, MaxPowerStored, APSBlockTypes.Machine);
		PowerLevel = 0;
		PowerIn = 0;
		PowerOut = 0;
		UserMaxPowerIn = MaxPowerIn;
		UserMaxPowerOut = MaxPowerOut;
		hasGUI = true;
		GuiID = GuiIDs.GUI_ENERGYSTORE;
	}
	
	@Override
	public void updateEntity()
	{		
		super.updateEntity();
		IsDraining = worldObj.isBlockIndirectlyGettingPowered(xCoord, yCoord, zCoord);
		PowerIn = 0;
		PowerOut = 0;
		
		if (IsDraining)
		{
			PowerOutDirection = getPoweredNeighbour();
			
			if (PowerOutDirection != null)
			{
				Position pos = new Position (xCoord, yCoord, zCoord, PowerOutDirection);
				
				pos.moveForwards(1);
				
				TileEntity tile = worldObj.getBlockTileEntity((int) pos.x, (int) pos.y, (int) pos.z);
				
				IPowerReceptor receptor = (IPowerReceptor) tile;
				float extracted;
				
				if (PowerLevel > UserMaxPowerOut)
					extracted = UserMaxPowerOut;
				else
					extracted  = PowerLevel;
				
				if (extracted > 0)
				{
					receptor.getPowerProvider().receiveEnergy(extracted, PowerOutDirection);
					PowerLevel -= extracted;
					PowerOut = extracted;
				}
			}
		}
		else
		{
			PowerIn = (float) powerProvider.useEnergy(1, (int) UserMaxPowerIn, true);
			PowerLevel += PowerIn;
		}
		
		if (PowerLevel > MaxPowerStored)
			PowerLevel = MaxPowerStored;
		else if (PowerLevel < 0)
			PowerLevel = 0;

		sendNetworkUpdate();
	}
	
	public int powerRequest()
	{
		if (IsDraining)
			return 0;
		else
		{
			int free = MaxPowerStored - PowerLevel;
			if (free >= MaxPowerIn) return UserMaxPowerIn;
			else return free;
		}
	}
	
	public void readFromNBT(NBTTagCompound nbttagcompound)
    {
    	super.readFromNBT(nbttagcompound);
		
    	PowerLevel = nbttagcompound.getInteger("powerlevel");
    	UserMaxPowerIn = nbttagcompound.getInteger("userpowerin");
    	UserMaxPowerOut = nbttagcompound.getInteger("userpowerout");
    	
    	
    }
	
    public void writeToNBT(NBTTagCompound nbttagcompound) {
    	super.writeToNBT(nbttagcompound);
    	
		nbttagcompound.setInteger("powerlevel", PowerLevel);
		nbttagcompound.setInteger("userpowerin", UserMaxPowerIn);
		nbttagcompound.setInteger("userpowerout", UserMaxPowerOut);
    }
	
	public boolean isDraining() {return IsDraining;}
	
	public float getScaledPower(boolean InputOutput, int MaxLevel)
	{
		if (InputOutput)
			return ((float) PowerOut / (float) MaxPowerOut) * MaxLevel;
		else
			return ((float) PowerIn / (float) MaxPowerIn) * MaxLevel;
	}
	
	public float getScaledPowerMax(boolean InputOutput, int MaxLevel)
	{
		if (InputOutput)
			return ((float) UserMaxPowerOut / (float) MaxPowerOut) * MaxLevel;
		else
			return ((float) UserMaxPowerIn / (float) MaxPowerIn) * MaxLevel;
	}
	
	public float getScaledPowerStored(int MaxLevel) {return ((float) PowerLevel / (float) MaxPowerStored) * MaxLevel;}

	@Override
	public void kill() {}

	@Override
	public InventoryAPS getInventory() {
		return null;
	}

	//@Override
	//public GuiScreen getGUI(EntityPlayer entityplayer) {
	//	return new GuiEnergyStore(this, entityplayer.inventory);
	//}

	/*@Override
	public LinkedList<ITrigger> getPipeTriggers(IPipe pipe) {
		return null;
	}

	@Override
	public LinkedList<ITrigger> getNeighborTriggers(Block block, TileEntity tile)
	{		
		LinkedList<ITrigger> triggers = new LinkedList<ITrigger>();
		
		if(tile instanceof TileEntityEnergyStore)
		{
			triggers.add(module_Machines.energyStoreFullTrigger);
			triggers.add(module_Machines.energyStoreEmptyTrigger);
			//triggers.add(module_Machines.energyStorePartFilledTrigger);
		}
		
		return triggers;
	}*/
	
	// -- NETWORKING -- //
	
	public void sendGUIUpdates(Container container, ICrafting iCrafting)
	{
		iCrafting.sendProgressBarUpdate(container, 0, this.PowerLevel);
		iCrafting.sendProgressBarUpdate(container, 1, (int)this.PowerIn);
		iCrafting.sendProgressBarUpdate(container, 2, (int)this.PowerOut);
	}
	
	public void getGUIUpdates(int channel, int value)
	{
		switch (channel)
		{
			case 0:
				this.PowerLevel = value;
				break;
			case 1:
				this.PowerIn = (float)value;
				break;
			case 2:
				this.PowerOut = (float)value;
				break;
		}
	}
	
	public PacketPayload getPacketPayload()
	{
		PacketPayload payload = new PacketPayload(2, 0, 0);
			payload.intPayload[0] = this.UserMaxPowerIn;
			payload.intPayload[1] = this.UserMaxPowerOut;
		return payload;
	}
	
	public void handleUpdatePacket(PacketUpdate packet)
	{
		this.UserMaxPowerIn = packet.payload.intPayload[0];
		this.UserMaxPowerOut = packet.payload.intPayload[1];
	}
	
	public void handleUpdateMessage(UpdateMessage message)
	{
		this.UserMaxPowerIn = message.maxIn;
		this.UserMaxPowerOut = message.maxOut;
	}
	
	public static class UpdateMessage {
		@TileNetworkData
		public int maxIn;
		
		@TileNetworkData
		public int maxOut;
	}
}